package cn.maihe.elg.operation.centers.hymake.channel.service;

import cn.maihe.elg.operation.centers.hymake.auth.HyMakeCenterAuthConfig;
import cn.maihe.elg.operation.centers.hymake.channel.HyMakeBaseChannelService;
import cn.maihe.elg.operation.centers.hymake.config.HyMakeInfoConfig;
import cn.maihe.elg.operation.centers.hymake.dto.channel.vo.xm.XMRevokeReqDTO;
import cn.maihe.elg.operation.centers.hymake.dto.handler.vo.xm.XMBaseRespDTO;
import cn.maihe.elg.operation.centers.hymake.enums.HyMakeChannelMethod;
import cn.maihe.elg.operation.centers.hymake.enums.HyMakeRespCodeEnum;
import cn.maihe.elg.operation.centers.hymake.enums.XMChannelMethod;
import cn.maihe.elg.operation.common.TradeContext;
import cn.maihe.elg.operation.exception.CenterException;
import cn.maihe.elg.operation.model.enums.CenterNoEnum;
import cn.maihe.elg.operation.model.enums.InnerRespCode;
import cn.maihe.elg.operation.service.invoice.InvoiceInfoService;
import cn.maihe.elg.operation.service.order.AcceptOrderInfoService;
import cn.maihe.elg.operation.service.order.GuaranteeAttachmentInfoService;
import cn.maihe.elg.operation.utils.ElgLogger;
import cn.maihe.elg.operation.utils.HttpUtil;
import cn.maihe.elg.operation.utils.ValidateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @Description 出函机构出函后通知 电子保函至平台侧
 * 出函机构（保险公司/银行）在出函后向电子保函平台推送电子保函的下载地址
 * @Author WJH
 * @Date 2021/04/21
 */
@Service
@Slf4j
public class XMRevokeChannelService extends HyMakeBaseChannelService<XMRevokeReqDTO, XMBaseRespDTO> {

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private AcceptOrderInfoService acceptOrderInfoService;
    @Resource
    private GuaranteeAttachmentInfoService guaranteeAttachmentInfoService;
    @Resource
    private InvoiceInfoService invoiceInfoService;

    @Resource
    private HyMakeInfoConfig hyMakeInfoConfig;

    private XMChannelMethod methodEnum = XMChannelMethod.revoke;

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected HyMakeChannelMethod methodEnum() {
        return HyMakeChannelMethod.bondDownLoad;
    }


    @Override
    public XMBaseRespDTO doRequest(CenterNoEnum centerNoEnum, XMRevokeReqDTO reqDTO, Map<String, Object> reqBody) {
        HyMakeCenterAuthConfig authConfig = hyMakeInfoConfig.getAuthConfig(centerNoEnum);

        //构建上下文
        TradeContext context = new TradeContext(reqDTO);
        try {
            //请求参数校验
            ValidateUtil.validate(reqDTO);
        } catch (Exception e) {
            CenterException ce = buildCException(InnerRespCode.FAILURE_PARAM, e, "参数错误:");
            ElgLogger.error(log, l -> l.error("traceId={} => 中心[{}][{}]服务 参数校验失败：{}", context.getTraceId(), centerNoEnum.getCenterNo(), methodEnum().getDesc(), ce.getMessage()));
            throw ce;
        }

        String json = JSONObject.toJSONString(reqDTO);

//        HyMakeHeaderInfo hyMakeHeaderInfo = HyMakeHeaderInfo.builder()
//                .appid(authConfig.getCenterInfo().getAppId())
//                .requestid(IdGenerate.getIdStr())
//                .timestamp(String.valueOf(System.currentTimeMillis()))
//                .version(authConfig.getCenterInfo().getVersion())
//                .build();

        //请求渠道服务
        String reqUrl = this.buildReqUrl(authConfig);
        try {
            ElgLogger.info(log, l -> l.info("traceId={} => 中心[{}][{}]服务 请求报文：{}", context.getTraceId(), centerNoEnum.getCenterNo(), methodEnum().getDesc(), reqBody.toString()));
            ElgLogger.info(log, l -> l.info("traceId={} => 中心[{}][{}]服务 请求地址：{}", context.getTraceId(), centerNoEnum.getCenterNo(), methodEnum().getDesc(), reqUrl));
//            HttpHeaders headers = new HttpHeaders();
//            BeanMap.create(hyMakeHeaderInfo).forEach((k, v) -> {
//                headers.add((String) k, (String) v);
//            });
//            headers.setContentType(MediaType.APPLICATION_JSON);
//
//            HttpEntity<String> request = new HttpEntity<>(json);
//            // todo 发送文件的地址好像不通
//            ResponseEntity<XMBaseRespDTO> responseEntity = restTemplate.postForEntity(reqUrl, request, XMBaseRespDTO.class);
            //发送PostFormData请求
            String responseStr = HttpUtil.doPostFormUrlencoded(reqUrl, reqBody);
            ElgLogger.info(log, l -> l.info("traceId={} <= 中心[{}][{}]服务 响应报文：{}", context.getTraceId(), centerNoEnum.getCenterNo(), methodEnum().getDesc(), responseStr));
            XMBaseRespDTO xmBaseRespDTO = JSON.parseObject(responseStr, XMBaseRespDTO.class);
            if (responseStr == null) {
                throw new RuntimeException("响应报文为空");
            } else {
                //正常响应业务处理
                if (!xmBaseRespDTO.getSuccess()) {
                    throw new RuntimeException("渠道侧接收失败:[" + xmBaseRespDTO.getErrorCode() + "," + xmBaseRespDTO.getErrorDesc() + "]");
                }
//                ElgLogger.info(log, l -> l.info("traceId={} <= 中心[{}][{}]服务 响应报文：{}", context.getTraceId(), centerNoEnum.getCenterNo(), methodEnum().getDesc(), this.toJsonString(xmBaseRespDTO)));
                ElgLogger.info(log, l -> l.info("traceId={} <= 中心[{}][{}]服务", context.getTraceId(), centerNoEnum.getCenterNo(), methodEnum().getDesc()));
                xmBaseRespDTO.setCode(HyMakeRespCodeEnum.SUCCESS.getRespCode());
                xmBaseRespDTO.setMessage(HyMakeRespCodeEnum.SUCCESS.getRespDesc());
                return xmBaseRespDTO;
            }

        } catch (Exception e) {
            CenterException ce = buildCException(InnerRespCode.FAILURE, e, "请求响应异常:");
            ElgLogger.error(log, l -> l.error("traceId={} <= 中心[{}][{}]服务 请求响应异常：{}", context.getTraceId(),
                    centerNoEnum.getCenterNo(), methodEnum().getDesc(), ce.getMessage()));
            throw ce;
        }

    }

    private String toJsonString(Object body) {
        if (body != null) {
            try {
                return objectMapper.writeValueAsString(body);
            } catch (JsonProcessingException e) {
                throw CenterException.exception("转换json字符串异常", e);
            }
        }
        return null;
    }


    private String buildReqUrl(HyMakeCenterAuthConfig authConfig) {
        String reUrl;
        String url = authConfig.getCenterInfo().getUrl().trim();
        if (url.endsWith("/")) {
            reUrl = url + methodEnum().getMethod();
        } else {
            reUrl = url + "/" + methodEnum().getMethod();
        }
        //若有特殊配置指定地址则已指定地址为准
        if (methodEnum == XMChannelMethod.revoke) {
            reUrl = url + XMChannelMethod.revoke.getMethod();
        }

        return reUrl;
    }
}
